const path = require("node:path");
const fs = require("node:fs");
const glob = require("glob");
const { arraify, XOR, isSame } = require('./utils.js');
const ScriptContext = require("./ScriptContext.js");

const DEFAULT_DEPENDJS = [
	"../../../../epmp/common/library/lib/index.js"
]

function analysisJS(scriptPath, commonComponents, analysedPath) {
	if (analysedPath.has(scriptPath)) {
		return;
	}
	analysedPath.add(scriptPath);
  const scriptContext = new ScriptContext(scriptPath);
  for (const scriptImport of scriptContext.imports) {
    const importFrom = scriptImport.importFrom;
    if (!importFrom) {
      console.log("有一个import没有from", scriptPath, scriptImport);
    }
    if (importFrom.startsWith(".")) {
      const importPath = path.resolve(path.dirname(scriptPath), importFrom);
      const extName = path.extname(importPath);
      if (extName === "js") {
        analysisJS(importPath, commonComponents, analysedPath);
      } else if (extName === "") {
        if (fs.existsSync(`${importPath}.js`)) {
          analysisJS(`${importPath}.js`, commonComponents, analysedPath);
        } else if (fs.existsSync(`${importPath}\\index.js`)) {
          analysisJS(`${importPath}\\index.js`, commonComponents, analysedPath);
        }
      }
    } else if (
      importFrom.startsWith("epmp") ||
      importFrom.startsWith("ufoe") ||
      importFrom.startsWith("ufoc") ||
      importFrom.startsWith("uap") ||
      importFrom.startsWith("uapbd")
    ) {
      commonComponents.add(importFrom);
    }
  }
}

function getDependJS(root, componentName, dependJS) {
  if (
    componentName.startsWith("epmp") ||
    componentName.startsWith("ufoe") ||
    componentName.startsWith("ufoc")
  ) {
    const configJSONPath = path.resolve(root, componentName, "config.json");
    const config = require(configJSONPath);
    if (!config.dependjs) {
      dependJS.add(`../../../../${componentName}/index.js`);
      return;
    }
    if (!Array.isArray(config.dependjs)) {
      config.dependjs = [config.dependjs];
    }
    for (const djs of config.dependjs) {
      dependJS.add(djs);
    }
    dependJS.add(`../../../../${componentName}/index.js`);
  } else {
    dependJS.add(`../../../../${componentName}/index.js`);
  }
}

function mkdirs(root, dirs) {
	if (dirs.length === 0) {
		return;
	}
	const dir = dirs.shift();
	const dirPath = path.resolve(root, dir);
	if (!fs.existsSync(dirPath)) {
		fs.mkdirSync(dirPath);
	}
	mkdirs(dirPath, dirs);
}

function saveScanResult(output, dependModuleName, dependjs) {
	const dirs = output.split("\\");
	const config = {
		output: dirs.join("/"),
		dependModuleName,
		dependjs
	}
	
	mkdirs(__dirname, ["result", ...dirs]);
	const outputDir = path.resolve(__dirname, "result", output);
	if (!fs.existsSync(outputDir)) {
		fs.mkdirSync(outputDir);
	}
	const outputPath = path.resolve(outputDir, "newConfig.json");
	fs.writeFileSync(outputPath, JSON.stringify(config, null, 2));
}

function process(total, complete) {
	const process = "".padStart(complete, "==").padEnd(total, "-");
	console.clear();
	console.log("[", process, "]", (((complete) / total) * 100).toFixed(2), "%");
}

/**
 * @param entries {string[]}
 */
function analysisMain(entries) {
  for (const [index, entry] of entries.entries()) {
    console.log("".padEnd(entry.length, "="));
    console.log(entry);
    console.log("".padEnd(entry.length, "="));
		const analysedPath = new Set();
    const commonComponents = new Set();
    analysisJS(entry, commonComponents, analysedPath);

    const dependJS = new Set();
		
		for (const djs of DEFAULT_DEPENDJS) {
			dependJS.add(djs);
		}
		
    for (const component of commonComponents) {
      getDependJS(root, component, dependJS);
    }

    const configJSON = require(path.resolve(
      path.dirname(entry),
      "config.json"
    ));
		
		
		arraify(configJSON, "dependModuleName");
		arraify(configJSON, "dependjs");
    //对比dependModuleName
    if (isSame([...commonComponents], configJSON.dependModuleName)) {
			//dependModuleName完全一样
			console.log("dependModuleName没问题，校验通过");
    } else {
			console.log("dependModuleName有差异，校验不通过");
			const [needAdd, needRemove] = XOR([...commonComponents], [...configJSON.dependModuleName]);
			console.log("需要删除的dependModuleName:", needRemove);
			console.log("需要新增的dependModuleName:", needAdd);
		}

		//对比dependjs
		if (isSame([...dependJS], configJSON.dependjs, DEFAULT_DEPENDJS)) {
			//dependModuleName完全一样
			console.log("dependjs没问题，校验通过");
		} else {
			console.log("dependjs有差异，校验不通过");
			const [needAdd, needRemove] = XOR([...dependJS], [...configJSON.dependjs], DEFAULT_DEPENDJS);
			console.log("需要删除的dependjs:", needRemove);
			console.log("需要新增的dependjs:", needAdd);
		}
		console.log("\n");
		
		saveScanResult(path.dirname(entry).split("src\\")[1], [...commonComponents], [...dependJS]);
		
		// process(entries.length, index + 1);
  }
}


const root = "D:\\WorkStation\\projects\\develop-ncc1.0\\src";

//校验公共组件的config.json
const p = path.resolve(root, "epmp/common/components/RuleDomBox/index.js").replaceAll("\\", "/");
analysisMain(glob.sync(p));

